package com.lry.basic.juc;

import java.lang.Object;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReadWriteLock;

/**
 * @author:刘仁有
 * @desc:
 * @email:953506233@qq.com
 * @data:2019/6/19
 */
public class ExclusiveLock {
    AtomicReference<Thread> sign = new AtomicReference();
    BlockingQueue<Thread> waiter = new LinkedBlockingQueue();
    public  void lock(){
        Thread thread = Thread.currentThread();
        while(!sign.compareAndSet(null,thread)){
            waiter.add(thread);
            //这里不可以用wait notify，因为notify不能唤醒指定的线程，只能用LockSupport
            LockSupport.park();
            waiter.remove(thread);
        }
    }

    public void unlock(){
        if(sign.compareAndSet(Thread.currentThread(),null)){
            Object[] arrs = waiter.toArray();
            for (Object obj:arrs) {
                LockSupport.unpark((Thread)obj);
            }
        }
    }

    static int i;
    static ExclusiveLock lock = new ExclusiveLock();
    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
        int concurrent=10000;
        final CyclicBarrier barrier = new CyclicBarrier(concurrent+1);
        final CountDownLatch cdl = new CountDownLatch(concurrent);
        for(int i=0;i<concurrent;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        cdl.await();
                        add();//10000个线程同时自增
                        barrier.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            cdl.countDown();
        }
        barrier.await();
        System.out.println(i);
    }
    public static void add(){
        lock.lock();
        i++;
        lock.unlock();
    }
}
